home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / initramfs-tools / scripts / casper < prev    next >
Encoding:
Text File  |  2009-04-18  |  17.5 KB  |  598 lines

  1. #!/bin/sh
  2.  
  3. # set -e
  4.  
  5. export PATH=/usr/bin:/usr/sbin:/bin:/sbin
  6.  
  7. mountpoint=/cdrom
  8.  
  9. root_persistence="casper-rw"
  10. home_persistence="home-rw"
  11. root_snapshot_label="casper-sn"
  12. home_snapshot_label="home-sn"
  13.  
  14. USERNAME=casper
  15. USERFULLNAME="Live session user"
  16. HOST=live
  17. BUILD_SYSTEM=Custom
  18.  
  19. mkdir -p $mountpoint
  20.  
  21. [ -f /etc/casper.conf ] && . /etc/casper.conf
  22. export USERNAME USERFULLNAME HOST BUILD_SYSTEM
  23.  
  24. . /scripts/casper-helpers
  25.  
  26. if [ ! -f /casper.vars ]; then
  27.     touch /casper.vars
  28. fi
  29.  
  30. parse_cmdline() {
  31.     for x in $(cat /proc/cmdline); do
  32.         case $x in
  33.             showmounts|show-cow)
  34.                 export SHOWMOUNTS='Yes' ;;
  35.             persistent)
  36.                 export PERSISTENT="Yes" ;;
  37.             nopersistent)
  38.                 export PERSISTENT="" ;;
  39.             union=*)
  40.                 export UNIONFS="${x#union=}";;
  41.             ip*)
  42.                 STATICIP=${x#ip=}
  43.                 if [ "${STATICIP}" = "" ]; then
  44.                     STATICIP="frommedia"
  45.                 fi
  46.                 export STATICIP ;;
  47.             ignore_uuid)
  48.                 IGNORE_UUID="Yes" ;;
  49.         esac
  50.     done
  51.     if [ "${UNIONFS}" = "" ]; then
  52.         export UNIONFS="aufs"
  53.     fi
  54. }
  55.  
  56. is_casper_path() {
  57.     path=$1
  58.     if [ -d "$path/casper" ]; then
  59.         if [ "$(echo $path/casper/*.squashfs)" != "$path/casper/*.squashfs" ] ||
  60.             [ "$(echo $path/casper/*.ext2)" != "$path/casper/*.ext2" ] ||
  61.             [ "$(echo $path/casper/*.dir)" != "$path/casper/*.dir" ]; then
  62.             return 0
  63.         fi
  64.     fi
  65.     return 1
  66. }
  67.  
  68. matches_uuid() {
  69.     if [ "$IGNORE_UUID" ] || [ ! -e /conf/uuid.conf ]; then
  70.         return 0
  71.     fi
  72.     path="$1"
  73.     uuid="$(cat /conf/uuid.conf)"
  74.     for try_uuid_file in "$path/.disk/casper-uuid"*; do
  75.         [ -e "$try_uuid_file" ] || continue
  76.         try_uuid="$(cat "$try_uuid_file")"
  77.         if [ "$uuid" = "$try_uuid" ]; then
  78.             return 0
  79.         fi
  80.     done
  81.     return 1
  82. }
  83.  
  84. get_backing_device() {
  85.     case "$1" in
  86.         *.squashfs|*.ext2)
  87.             echo $(setup_loop "$1" "loop" "/sys/block/loop*")
  88.             ;;
  89.         *.dir)
  90.             echo "directory"
  91.             ;;
  92.         *)
  93.             panic "Unrecognized casper filesystem: $1"
  94.             ;;
  95.     esac
  96. }
  97.  
  98. match_files_in_dir() {
  99.     # Does any files match pattern $1 ?
  100.  
  101.     local pattern="$1"
  102.     if [ "$(echo $pattern)" != "$pattern" ]; then
  103.         return 0
  104.     fi
  105.     return 1
  106. }
  107.  
  108. mount_images_in_directory() {
  109.     directory="$1"
  110.     rootmnt="$2"
  111.     if match_files_in_dir "$directory/casper/*.squashfs" ||
  112.         match_files_in_dir "$directory/casper/*.ext2" ||
  113.         match_files_in_dir "$directory/casper/*.dir"; then
  114.         setup_unionfs "$directory/casper" "$rootmnt"
  115.     else
  116.         :
  117.     fi
  118. }
  119.  
  120. is_nice_device() {
  121.     sysfs_path="${1#/sys}"
  122.     if /lib/udev/path_id "${sysfs_path}" | grep -E -q "ID_PATH=(usb|pci-[^-]*-(ide|scsi|usb)|platform-mmc)"; then
  123.         return 0
  124.     fi
  125.     return 1
  126. }
  127.  
  128. copy_live_to() {
  129.     copyfrom="${1}"
  130.     copytodev="${2}"
  131.     copyto="${copyfrom}_swap"
  132.  
  133.     size=$(fs_size "" ${copyfrom} "used")
  134.  
  135.     if [ "${copytodev}" = "ram" ]; then
  136.         # copying to ram:
  137.         freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - ) )
  138.         mount_options="-o size=${size}k"
  139.         free_string="memory"
  140.         fstype="tmpfs"
  141.         dev="/dev/shm"
  142.     else
  143.         # it should be a writable block device
  144.         if [ -b "${copytodev}" ]; then
  145.             dev="${copytodev}"
  146.             free_string="space"
  147.             fstype=$(get_fstype "${dev}")
  148.             freespace=$(fs_size "${dev}")
  149.         else
  150.             [ "$quiet" != "y" ] && log_warning_msg "${copytodev} is not a block device."
  151.             return 1
  152.         fi
  153.     fi
  154.     if [ "${freespace}" -lt "${size}" ] ; then
  155.         [ "$quiet" != "y" ] && log_warning_msg "Not enough free ${free_string} (${freespace}k > ${size}k) to copy live media in ${copytodev}."
  156.         return 1
  157.     fi
  158.  
  159.     # begin copying..
  160.     mkdir "${copyto}"
  161.     echo "mount -t ${fstype} ${mount_options} ${dev} ${copyto}"
  162.     mount -t "${fstype}" ${mount_options} "${dev}" "${copyto}"
  163.     cp -a ${copyfrom}/* ${copyto} # "cp -a" from busybox also copies hidden files
  164.     umount ${copyfrom}
  165.     mount -r -o move ${copyto} ${copyfrom}
  166.     rmdir ${copyto}
  167.     return 0
  168. }
  169.  
  170. do_netmount() {
  171.     rc=1
  172.  
  173.     modprobe "${MP_QUIET}" af_packet # For DHCP
  174.  
  175.     /sbin/udevadm trigger
  176.     /sbin/udevadm settle
  177.  
  178.     ipconfig ${DEVICE} /tmp/net-${DEVICE}.conf | tee /netboot.config
  179.  
  180.     if [ "${NFSROOT}" = "auto" ]; then
  181.         NFSROOT=${ROOTSERVER}:${ROOTPATH}
  182.     fi
  183.  
  184.     [ "$quiet" != "y" ] && log_begin_msg "Trying netboot from ${NFSROOT}"
  185.  
  186.     if [ "${NETBOOT}" != "nfs" ] && do_cifsmount ; then
  187.         rc=0
  188.     elif do_nfsmount ; then
  189.         NETBOOT="nfs"
  190.         export NETBOOT
  191.         rc=0
  192.     fi
  193.  
  194.     [ "$quiet" != "y" ] && log_end_msg
  195.     return ${rc}
  196. }
  197.  
  198. do_nfsmount() {
  199.     rc=1
  200.     modprobe "${MP_QUIET}" nfs
  201.     if [ -z "${NFSOPTS}" ]; then
  202.         NFSOPTS=""
  203.     fi
  204.  
  205.     [ "$quiet" != "y" ] && log_begin_msg "Trying nfsmount -o nolock -o ro ${NFSOPTS} ${NFSROOT} ${mountpoint}"
  206.     # FIXME: This while loop is an ugly HACK round an nfs bug
  207.     i=0
  208.     while [ "$i" -lt 60 ]; do
  209.         nfsmount -o nolock -o ro ${NFSOPTS} "${NFSROOT}" "${mountpoint}" && rc=0 && break
  210.         sleep 1
  211.         i="$(($i + 1))"
  212.     done
  213.     return ${rc}
  214. }
  215.  
  216. do_cifsmount() {
  217.     rc=1
  218.     if [ -x "/sbin/mount.cifs" ]; then
  219.         if [ -z "${NFSOPTS}" ]; then
  220.             CIFSOPTS="-ouser=root,password="
  221.         else
  222.             CIFSOPTS="${NFSOPTS}"
  223.         fi
  224.  
  225.         [ "$quiet" != "y" ] && log_begin_msg "Trying mount.cifs ${NFSROOT} ${mountpoint} ${CIFSOPTS}"
  226.         modprobe "${MP_QUIET}" cifs
  227.  
  228.         if mount.cifs "${NFSROOT}" "${mountpoint}" "${CIFSOPTS}" ; then
  229.             rc=0
  230.         fi
  231.     fi
  232.     return ${rc}
  233. }
  234.  
  235. do_snap_copy ()
  236. {
  237.     fromdev="${1}"
  238.     todir="${2}"
  239.     snap_type="${3}"
  240.  
  241.     size=$(fs_size "${fromdev}" "" "used")
  242.  
  243.     if [ -b "${fromdev}" ]; then
  244.         # look for free mem
  245.         if [ -n "${HOMEMOUNTED}" -a "${snap_type}" = "HOME" ]; then
  246.             todev=$(cat /proc/mounts | grep -s " $(base_path ${todir}) " | awk '{print $1}' )
  247.             freespace=$(df -k  | grep -s ${todev} | awk '{print $4}')
  248.         else
  249.             freespace=$( expr $(awk '/MemFree/{print $2}' /proc/meminfo) + $( cat /proc/meminfo | grep Cached | head -n 1 | awk '/Cached/{print $2}' - ))
  250.         fi
  251.  
  252.         tomount="/mnt/tmpsnap"
  253.         if [ ! -d "${tomount}" ] ; then
  254.             mkdir -p "${tomount}"
  255.         fi
  256.  
  257.         fstype=$(get_fstype "${fromdev}")
  258.         if [ -n "${fstype}" ]; then
  259.             # Copying stuff...
  260.             mount -t "${fstype}" -o ro,noatime "${fromdev}" "${tomount}"
  261.             cp -a "${tomount}"/* ${todir}
  262.             umount "${tomount}"
  263.         else
  264.             log_warning_msg "Unrecognized fstype: ${fstype} on ${fromdev}:${snap_type}"
  265.         fi
  266.  
  267.         rmdir "${tomount}"
  268.         if echo ${fromdev} | grep -qs loop; then
  269.            losetup -d "${fromdev}"
  270.         fi
  271.         return 0
  272.     else
  273.         return 1
  274.         [ "$quiet" != "y" ] && log_warning_msg "Unable to find the snapshot ${snap_type} medium"
  275.     fi
  276. }
  277.  
  278. try_snap ()
  279. {
  280.     # Look for $snap_label.* in block devices and copy the contents to $snap_mount
  281.     #   and remember the device and filename for resync on exit in casper.init
  282.  
  283.     snap_label="${1}"
  284.     snap_mount="${2}"
  285.     snap_type="${3}"
  286.  
  287.     snapdata=$(find_files "${snap_label}.squashfs ${snap_label}.cpio.gz ${snap_label}.ext2")
  288.     if [ ! -z "${snapdata}" ]; then
  289.         snapdev="$(echo ${snapdata} | cut -f1 -d ' ')"
  290.         snapback="$(echo ${snapdata} | cut -f2 -d ' ')"
  291.         snapfile="$(echo ${snapdata} | cut -f3 -d ' ')"
  292.         if echo "${snapfile}" | grep -qs '\(squashfs\|ext2\)'; then
  293.             # squashfs or ext2 snapshot
  294.             dev=$(get_backing_device "${snapback}/${snapfile}")
  295.             if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}"; then
  296.                  log_warning_msg "Impossible to include the ${snapfile} Snapshot"
  297.                  return 1
  298.             fi
  299.         else
  300.             # cpio.gz snapshot
  301.             if ! (cd "${snap_mount}" && zcat "${snapback}/${snapfile}" | cpio -i -u -d 2>/dev/null) ; then
  302.                 log_warning_msg "Impossible to include the ${snapfile} Snapshot"
  303.                 return 1
  304.             fi
  305.         fi
  306.         umount "${snapback}"
  307.     else
  308.         dev=$(find_cow_device "${snap_label}")
  309.         if [ -b ${dev} ]; then
  310.             if echo "${dev}" | grep -qs loop; then
  311.                 # strange things happens, user confused?
  312.                 snaploop=$( losetup ${dev} | awk '{print $3}' | tr -d '()' )
  313.                 snapfile=$(basename ${snaploop})
  314.                 snapdev=$(cat /proc/mounts | awk '{print $2,$1}' | grep -es "^$( dirname ${snaploop} )" | cut -f2 -d ' ')
  315.             else
  316.                 snapdev="${dev}"
  317.             fi
  318.             if ! do_snap_copy "${dev}" "${snap_mount}" "${snap_type}" ; then
  319.                 log_warning_msg "Impossible to include the ${snap_label} Snapshot"
  320.                 return 1
  321.             else
  322.                 if [ -n "${snapfile}" ]; then
  323.                      # it was a loop device, user confused
  324.                      umount ${snapdev}
  325.                 fi
  326.             fi
  327.         else
  328.             log_warning_msg "Impossible to include the ${snap_label} Snapshot"
  329.             return 1
  330.         fi
  331.     fi
  332.     echo "export ${snap_type}SNAP="${snap_mount}":${snapdev}:${snapfile}" >> /etc/casper.conf # for resync on reboot/halt
  333.     return 0
  334. }
  335.  
  336. setup_unionfs() {
  337.     image_directory="$1"
  338.     rootmnt="$2"
  339.  
  340.     modprobe "${MP_QUIET}" -b ${UNIONFS}
  341.  
  342.     # run-init can't deal with images in a subdir, but we're going to
  343.     # move all of these away before it runs anyway.  No, we're not,
  344.     # put them in / since move-mounting them into / breaks mono and
  345.     # some other apps.
  346.  
  347.     croot="/"
  348.  
  349.     # Let's just mount the read-only file systems first
  350.     rofsstring=""
  351.     rofslist=""
  352.     if [ "${NETBOOT}" = "nfs" ] ; then
  353.         roopt="nfsro" # go aroung a bug in nfs-unionfs locking
  354.     elif [ "${UNIONFS}" = "aufs" ]; then
  355.         roopt="rr"
  356.     else
  357.         roopt="ro"
  358.     fi
  359.  
  360.     mkdir -p "${croot}"
  361.     for image_type in "ext2" "squashfs" "dir" ; do
  362.         for image in "${image_directory}"/*."${image_type}"; do
  363.             imagename=$(basename "${image}")
  364.             if [ -d "${image}" ]; then
  365.                 # it is a plain directory: do nothing
  366.                 rofsstring="${image}=${roopt}:${rofsstring}"
  367.                 rofslist="${image} ${rofslist}"
  368.             elif [ -f "${image}" ]; then
  369.                 backdev=$(get_backing_device "$image")
  370.                 fstype=$(get_fstype "${backdev}")
  371.                 if [ "${fstype}" = "unknown" ]; then
  372.                     panic "Unknown file system type on ${backdev} (${image})"
  373.                 fi
  374.                 mkdir -p "${croot}/${imagename}"
  375.                 mount -t "${fstype}" -o ro,noatime "${backdev}" "${croot}/${imagename}" || panic "Can not mount $backdev ($image) on ${croot}/${imagename}" && rofsstring="${croot}/${imagename}=${roopt}:${rofsstring}" && rofslist="${croot}/${imagename} ${rofslist}"
  376.             fi
  377.         done
  378.     done
  379.     rofsstring=${rofsstring%:}
  380.  
  381.     mkdir -p /cow
  382.     cowdevice="tmpfs"
  383.     cow_fstype="tmpfs"
  384.     cow_mountopt="rw,noatime,mode=755"
  385.  
  386.     # Looking for "${root_persistence}" device or file
  387.     if [ -n "${PERSISTENT}" ]; then
  388.         cowprobe=$(find_cow_device "${root_persistence}")
  389.         if [ -b "${cowprobe}" ]; then
  390.             cowdevice=${cowprobe}
  391.             cow_fstype=$(get_fstype "${cowprobe}")
  392.         cow_mountopt="rw,noatime"
  393.         else
  394.             [ "$quiet" != "y" ] && log_warning_msg "Unable to find the persistent medium"
  395.         fi
  396.     fi
  397.  
  398.     mount -t ${cow_fstype} -o ${cow_mountopt} ${cowdevice} /cow || panic "Can not mount $cowdevice on /cow"
  399.  
  400.     mount -t ${UNIONFS} -o noatime,dirs=/cow=rw:$rofsstring ${UNIONFS} "$rootmnt" || panic "${UNIONFS} mount failed"
  401.  
  402.     # Adding other custom mounts
  403.     if [ -n "${PERSISTENT}" ]; then
  404.         # directly mount /home
  405.         # FIXME: add a custom mounts configurable system
  406.         homecow=$(find_cow_device "${home_persistence}" )
  407.         if [ -b "${homecow}" ]; then
  408.             mount -t $(get_fstype "${homecow}") -o rw,noatime "${homecow}" "${rootmnt}/home"
  409.             export HOMEMOUNTED=1 # used to proper calculate free space in do_snap_copy()
  410.         else
  411.             [ "$quiet" != "y" ] && log_warning_msg "Unable to find the persistent home medium"
  412.         fi
  413.         # Look for other snapshots to copy in
  414.         try_snap "${root_snapshot_label}" "${rootmnt}" "ROOT"
  415.         try_snap "${home_snapshot_label}" "${rootmnt}/home" "HOME"
  416.     fi
  417.  
  418.     if [ -n "${SHOWMOUNTS}" ]; then
  419.         for d in ${rofslist}; do
  420.             mkdir -p "${rootmnt}/casper/${d##*/}"
  421.             case d in
  422.                 *.dir) # do nothing # mount -o bind "${d}" "${rootmnt}/casper/${d##*/}"
  423.                     ;;
  424.                 *) mount -o move "${d}" "${rootmnt}/casper/${d##*/}"
  425.                     ;;
  426.             esac
  427.         done
  428.         # shows cow fs on /cow for use by casper-snapshot
  429.         mkdir -p "${rootmnt}/cow"
  430.         mount -o bind /cow "${rootmnt}/cow"
  431.     fi
  432.  
  433.     # move the first mount; no head in busybox-initramfs
  434.     for d in $(mount -t squashfs | cut -d\  -f 3); do
  435.         mkdir -p "${rootmnt}/rofs"
  436.         mount -o move "${d}" "${rootmnt}/rofs"
  437.         break
  438.     done
  439. }
  440.  
  441. check_dev ()
  442. {
  443.     sysdev="${1}"
  444.     devname="${2}"
  445.     skip_uuid_check="${3}"
  446.     if [ -z "${devname}" ]; then
  447.         devname=$(sys2dev "${sysdev}")
  448.     fi
  449.  
  450.     if [ -d "${devname}" ]; then
  451.         mount -o bind "${devname}" $mountpoint || continue
  452.         if is_casper_path $mountpoint; then
  453.             echo $mountpoint
  454.             return 0
  455.         else
  456.             umount $mountpoint
  457.         fi
  458.     fi
  459.  
  460.     if [ -n "${LIVEMEDIA_OFFSET}" ]; then
  461.         loopdevname=$(setup_loop "${devname}" "loop" "/sys/block/loop*" "${LIVEMEDIA_OFFSET}")
  462.         devname="${loopdevname}" 
  463.     fi
  464.  
  465.     fstype=$(get_fstype "${devname}")
  466.     if is_supported_fs ${fstype}; then
  467.         mount -t ${fstype} -o ro,noatime "${devname}" $mountpoint || continue
  468.         if is_casper_path $mountpoint && \
  469.            ([ "$skip_uuid_check" ] || matches_uuid $mountpoint); then
  470.             echo $mountpoint
  471.             return 0
  472.         else
  473.             umount $mountpoint
  474.         fi
  475.     fi
  476.  
  477.     if [ -n "${LIVEMEDIA_OFFSET}" ]; then
  478.         losetup -d "${loopdevname}"
  479.     fi
  480.     return 1
  481. }
  482.  
  483. find_livefs() {
  484.     timeout="${1}"
  485.     # first look at the one specified in the command line
  486.     if [ ! -z "${LIVEMEDIA}" ]; then
  487.         if check_dev "null" "${LIVEMEDIA}" "skip_uuid_check"; then
  488.             return 0
  489.         fi
  490.     fi
  491.     # don't start autodetection before timeout has expired
  492.     if [ -n "${LIVEMEDIA_TIMEOUT}" ]; then
  493.         if [ "${timeout}" -lt "${LIVEMEDIA_TIMEOUT}" ]; then
  494.             return 1
  495.         fi
  496.     fi
  497.     # or do the scan of block devices
  498.     for sysblock in $(echo /sys/block/* | tr ' ' '\n' | grep -vE "/(loop|ram|fd)"); do
  499.         devname=$(sys2dev "${sysblock}")
  500.         fstype=$(get_fstype "${devname}")
  501.         if /lib/udev/cdrom_id ${devname} > /dev/null; then
  502.             if check_dev "null" "${devname}" ; then
  503.                 return 0
  504.             fi
  505.         elif is_nice_device "${sysblock}" ; then
  506.             for dev in $(subdevices "${sysblock}"); do
  507.                 if check_dev "${dev}" ; then
  508.                     return 0
  509.                 fi
  510.             done
  511.         elif [ "${fstype}" = "squashfs" -o \
  512.                 "${fstype}" = "ext4" -o \
  513.                 "${fstype}" = "ext3" -o \
  514.                 "${fstype}" = "ext2" ]; then
  515.             # This is an ugly hack situation, the block device has
  516.             # an image directly on it.  It's hopefully
  517.             # casper, so take it and run with it.
  518.             ln -s "${devname}" "${devname}.${fstype}"
  519.             echo "${devname}.${fstype}"
  520.             return 0
  521.         fi
  522.     done
  523.     return 1
  524. }
  525.  
  526. set_usplash_timeout() {
  527.     if [ -x /sbin/usplash_write ]; then
  528.         /sbin/usplash_write "TIMEOUT 120"
  529.     fi
  530. }
  531.  
  532. mountroot() {
  533.     exec 6>&1
  534.     exec 7>&2
  535.     exec > casper.log
  536.     exec 2>&1
  537.  
  538.     parse_cmdline
  539.  
  540.     set_usplash_timeout
  541.     [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/casper-premount"
  542.     run_scripts /scripts/casper-premount
  543.     [ "$quiet" != "y" ] && log_end_msg
  544.  
  545.     # Needed here too because some things (*cough* udev *cough*)
  546.     # changes the timeout
  547.  
  548.     set_usplash_timeout
  549.  
  550.     if [ ! -z "${NETBOOT}" ]; then
  551.         if do_netmount ; then
  552.             livefs_root="${mountpoint}"
  553.         else
  554.             panic "Unable to find a live file system on the network"
  555.         fi
  556.     else
  557.         # Scan local devices for the image
  558.         i=0
  559.         while [ "$i" -lt 60 ]; do
  560.             livefs_root=$(find_livefs $i)
  561.             if [ "${livefs_root}" ]; then
  562.                 break
  563.             fi
  564.             sleep 1
  565.             i="$(($i + 1))"
  566.         done
  567.     fi
  568.  
  569.     if [ -z "${livefs_root}" ]; then
  570.         panic "Unable to find a medium containing a live file system"
  571.     fi
  572.  
  573.     if [ "${TORAM}" ]; then
  574.         live_dest="ram"
  575.     elif [ "${TODISK}" ]; then
  576.         live_dest="${TODISK}"
  577.     fi
  578.     if [ "${live_dest}" ]; then
  579.         log_begin_msg "Copying live_media to ${live_dest}"
  580.         copy_live_to "${livefs_root}" "${live_dest}"
  581.         log_end_msg
  582.     fi
  583.  
  584.     mount_images_in_directory "${livefs_root}" "${rootmnt}"
  585.  
  586.     log_end_msg
  587.  
  588.     maybe_break casper-bottom
  589.     [ "$quiet" != "y" ] && log_begin_msg "Running /scripts/casper-bottom"
  590.  
  591.     run_scripts /scripts/casper-bottom
  592.     [ "$quiet" != "y" ] && log_end_msg
  593.  
  594.     exec 1>&6 6>&-
  595.     exec 2>&7 7>&-
  596.     cp casper.log "${rootmnt}/var/log/"
  597. }
  598.